package com.my_musc_service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.my_musc_service.config.ServerConfig;
import com.my_musc_service.dao.SingerDao;
import com.my_musc_service.dao.SongDao;
import com.my_musc_service.dao.UserDao;
import com.my_musc_service.entity.SharedSong;
import com.my_musc_service.entity.Singer;
import com.my_musc_service.entity.Song;
import com.my_musc_service.entity.User;
import com.my_musc_service.exception.CustomException;
import com.my_musc_service.interceptor.LoginInterceptor;
import com.my_musc_service.service.UploadService;
import com.my_musc_service.utils.FileTypeUtils;
import com.my_musc_service.utils.UploadFileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zhudunfeng
 * @date 2021/6/15 22:39
 */
@Service
public class UploadServiceImpl implements UploadService {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
    @Autowired
    private SharedSongServiceImpl sharedSongService;

    @Autowired
    private SongDao songDao;
    @Autowired
    private SingerDao singerDao;

    @Autowired
    private UserDao userDao;
    @Autowired
    private ServerConfig serverConfig;
    @Value("${server.port}")
    private String port;
    //绑定文件上传路径到uploadPath
    @Value("${web.upload-path}")
    private String uploadPath;

    public String getUrl() {
        return serverConfig.getUrl();
    }

    @Override
    public String upload(MultipartFile songFile,
                         MultipartFile lyricFile,
                         MultipartFile coverFile,
                         Song song,
                         HttpServletRequest request) {
        String name = song.getName();
        String singer = song.getSinger();
        String description = song.getDescript();

        // 在 uploadPath 文件夹中通过日期对上传的文件归类保存
        // 比如：/2019/06/06/cf13891e-4b95-4000-81eb-b6d70ae44930.png
        String format = sdf.format(new Date());
        File folder = createNewFolder(format);

        // 对上传的文件重命名，避免文件重名
        String newSongName = getNewFileName(songFile);
        String newLyricName = getNewFileName(lyricFile);
        String newCoverName = getNewFileName(coverFile);

        try {
            // 文件保存
            saveFile(songFile, folder, newSongName);
            saveFile(lyricFile, folder, newLyricName);
            saveFile(coverFile, folder, newCoverName);

//            // 歌曲url
//            String songFilePath = request.getScheme() + "://" + request.getServerName()
//                    + ":" + request.getServerPort() + "/" + format + newSongName;
//
//            // 歌词url
//            String lytricFilePath = request.getScheme() + "://" + request.getServerName()
//                    + ":" + request.getServerPort() + "/" + format + newLyricName;
            // 歌曲url
            String songFilePath = getFilePath(format, newSongName);
            // 歌词url
            String lytricFilePath = getFilePath(format, newLyricName);
            // 封面url
            String coverFilePath = getFilePath(format, newCoverName);

            if (StringUtils.isNotBlank(lytricFilePath)) {
                song.setLyric(lytricFilePath);
            }

            //保存到数据库
            QueryWrapper<Song> songQueryWrapper = new QueryWrapper<>();
            Song songData = songDao.selectOne(songQueryWrapper.eq("id", song.getId()));
            if (songData != null) {
                saveSong(name, singer, description, songFilePath, lytricFilePath, coverFilePath, songData);
            } else {
                Song songNew = new Song();
                saveSong(name, singer, description, songFilePath, lytricFilePath, coverFilePath, songNew);
                //歌曲上传，添加分享
                saveSharedSong(name, description, songNew);
            }


            return songFilePath;
        } catch (IOException e) {
            System.out.println(e);
            throw new CustomException("文件保存异常");
        }


    }

    private void saveSharedSong(String name, String description, Song songNew) {
        Song songDataNew = songDao.selectOne(new QueryWrapper<Song>().setEntity(songNew));
        SharedSong sharedSong = new SharedSong();
        sharedSong.setSongId(songDataNew.getId());
        sharedSong.setSongName(name);
        Integer userId = Optional.ofNullable(LoginInterceptor.getUserInfo()).map(User::getId).orElse(null);
        if (userId != null) {
            sharedSong.setUserId(userId);
        }
        sharedSong.setDescription(description);

        //添加到歌曲分享
        sharedSongService.insert(sharedSong);
    }

    private String getNewFileName(MultipartFile file) {
        String newFileName = null;
        if (file != null) {
            String oldFileName = file.getOriginalFilename();
            String extension = FilenameUtils.getExtension(oldFileName);
            if(!FileTypeUtils.checkFileExtension(extension)){
                throw new CustomException("不允许的文件类型:"+extension);
            }
            newFileName = UUID.randomUUID().toString()
                    + oldFileName.substring(oldFileName.lastIndexOf("."), oldFileName.length());
        }
        return newFileName;
    }

    private void saveFile(MultipartFile file, File folder, String newFileName) throws IOException {
        if (file != null) {
            File newFile = new File(folder, newFileName);
            if (!newFile.exists()) {
                newFile.createNewFile();
            }
            file.transferTo(newFile.getAbsoluteFile());
        }
    }

    private String getFilePath(String format, String newFileName) {
        String filePath = null;
        if (StringUtils.isNotBlank(newFileName)) {
            filePath = getUrl() + "/music/" + format + newFileName;
        }
        return filePath;
    }


    private void saveSong(String name, String singer, String description, String songFilePath, String lytricFilePath, String coverFilePath, Song songData) {
        songData.setName(name);
        songData.setSinger(singer);
        if (StringUtils.isNotBlank(songFilePath)) {
            songData.setUrl(songFilePath);
        }
        songData.setDescript(description);

        if (StringUtils.isNotBlank(lytricFilePath)) {
            songData.setLyric(lytricFilePath);
        }

        if (StringUtils.isNotBlank(coverFilePath)) {
            songData.setCoverUrl(coverFilePath);
        }

        List<Song> songs = new ArrayList<>();
        songs.add(songData);
        songDao.insertOrUpdateBatch(songs);
    }

    private File createNewFolder(String format) {
        File folder = new File(uploadPath + format);
        if (!folder.isDirectory() || !folder.exists()) {
            folder.mkdirs();
        }
        return folder;
    }

    @Override
    public String uploadSingerImg(String singer, MultipartFile singerImg) {

        // 在 uploadPath 文件夹中通过日期对上传的文件归类保存
        // 比如：/2019/06/06/cf13891e-4b95-4000-81eb-b6d70ae44930.png
        String format = sdf.format(new Date());
        File folder = createNewFolder(format);

        // 对上传的文件重命名，避免文件重名
        String oldSingerImgName = singerImg.getOriginalFilename();
        String newSingerImgName = UUID.randomUUID().toString()
                + oldSingerImgName.substring(oldSingerImgName.lastIndexOf("."), oldSingerImgName.length());
        try {
            // 文件保存
            File singerImgDesc = new File(folder, newSingerImgName);
            if (!singerImgDesc.exists()) {
                singerImgDesc.createNewFile();
            }
            singerImg.transferTo(singerImgDesc.getAbsoluteFile());

            // 歌曲url
            String singerImgPath = getUrl() + "/music/" + format + newSingerImgName;

            //保存到数据库
            Singer singerModel = new Singer();
            singerModel.setName(singer);
            singerModel.setPosterUrl(singerImgPath);
            singerDao.insert(singerModel);
            return singerImgPath;
        } catch (IOException e) {
            System.out.println(e);
            throw new CustomException("歌手图片保存异常");
        }
    }

    @Override
    public String uploadHeaderImg(Integer userId, MultipartFile headerImg) {

        //保存到数据库
        User user = userDao.selectOne(new QueryWrapper<User>().eq("id", userId));
        if(user == null){
            throw new CustomException("没有当前User:"+userId);
        }

        //删除原头像文件
        String headerImgUrl = user.getHeaderImgUrl();
        if (StringUtils.isNotBlank(headerImgUrl)) {
            UploadFileUtils.deleteFile(uploadPath ,headerImgUrl);
        }
        // 在 uploadPath 文件夹中通过日期对上传的文件归类保存
        // 比如：/2019/06/06/cf13891e-4b95-4000-81eb-b6d70ae44930.png
        String format = sdf.format(new Date());
        File folder = createNewFolder(format);
        String newFileName = getNewFileName(headerImg);
        try {
            saveFile(headerImg, folder, newFileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String filePath = getFilePath(format, newFileName);
        user.setHeaderImgUrl(filePath);
        int update = userDao.update(user);

        return filePath;
    }

}
